<template>
	<el-card shadow="hover" body-style="padding: 10px 10px 10px 15px">
		<template #header>
			<div class="card_header">
				<div class="card_header_left">待办事项</div>
				<div class="card_header_right">
					<!-- 删除按钮 -->
					<el-popconfirm
						width="320"
						icon-color="#626AEF"
						title="确定要删除所有【已完成】的待办事项吗？"
						confirm-button-text="是的"
						cancel-button-text="取消"
						@confirm="onConfirmDelete"
					>
						<template #reference>
							<HIcon
								name="ele-DeleteFilled"
								class="cursor-pointer mr10"
								color="#909399"
								title="删除"
								:size="20"
							/>
						</template>
					</el-popconfirm>
					<!-- 添加按钮 -->
					<HIcon
						name="ele-CirclePlusFilled"
						ref="addIconRef"
						class="cursor-pointer"
						color="#409eff"
						title="添加"
						:size="20"
					/>
					<el-popover
						ref="settingRef"
						v-model:visible="showAddInput"
						:virtual-ref="addIconRef"
						virtual-triggering
						trigger="click"
						placement="bottom-end"
						transition="el-zoom-in-top"
						width="550"
						@after-enter="() => addInputRef.focus()"
					>
						<el-input
							ref="addInputRef"
							v-model="addListText"
							type="textarea"
							:autosize="{ minRows: 3, maxRows: 6 }"
							placeholder="请输入待办事项内容，按回车键添加到列表中"
							@keyup.enter="onConfirmAdd"
						/>
					</el-popover>
				</div>
			</div>
		</template>
		<div v-if="listData.length > 0" ref="listContainerRef" class="list-container">
			<div class="list-item" v-for="item in listData" :key="item.id" :data-key="item.id">
				<div class="list-status">
					<HIcon
						:name="listStatusMap[item.status].icon"
						:color="listStatusMap[item.status].color"
						:size="30"
					/>
				</div>
				<div class="list-mid">
					<div
						class="list-item-content"
						:style="{ textDecorationLine: item.isCheck ? 'line-through' : 'none' }"
					>
						{{ item.content }}
					</div>
					<div class="list-item-sort cursor-grab">
						<HIcon name="fa fa-align-justify" color="#909399" title="按住可拖动" />
					</div>
					<!-- <div class="list-item-sort cursor-grab">
						<HIcon name="ele-DCaret" color="#909399" :size="20" title="按住可拖动" />
					</div> -->
				</div>
				<div class="list-right">
					<div class="list-item-check">
						<el-checkbox
							v-model="item.isCheck"
							:label="listStatusMap[item.status].label"
							:border="true"
							@change="(value: boolean) => onCheckChange(item.id, value)"
						/>
					</div>
				</div>
			</div>
		</div>
		<el-empty v-else description="暂无待办事项" />
	</el-card>
</template>

<script setup lang="ts" name="todoList">
import { ref, watch, onMounted, onBeforeUnmount } from "vue";
import { storeToRefs } from "pinia";
import { useUserInfo } from "/@/stores/userInfo";
import { Local } from "/@/utils/storage";
import { debounce } from "lodash";
import Sortable from "sortablejs";

// 定义变量
const { userInfo } = storeToRefs(useUserInfo());
const addIconRef = ref();
const addInputRef = ref();
const addListText = ref("");
const showAddInput = ref(false);
const listContainerRef = ref();
const listData = ref<{ id: number | string; status: number; isCheck: boolean; content: string }[]>([]);
const listStatusMap = {
	1: {
		icon: "ele-SuccessFilled",
		color: "#67c23a",
		label: "已完成",
	},
	2: {
		icon: "ele-WarningFilled",
		color: "#e6a23c",
		label: "待处理",
	},
};

// 初始化 todoList
if (Local.has(`todoList--${userInfo.value.id}`)) {
	listData.value = Local.get(`todoList--${userInfo.value.id}`);
} else {
	Local.set(`todoList--${userInfo.value.id}`, []);
}

// 删除待办事项（所有已完成的）
const onConfirmDelete = () => {
	listData.value = listData.value.filter(item => item.status === 2);
};

// 添加待办事项
const onConfirmAdd = () => {
	if (addListText.value.trim() === "") return;
	listData.value.unshift({
		id: Date.now(),
		status: 2,
		isCheck: false,
		content: addListText.value,
	});
	addListText.value = "";
	showAddInput.value = false;
};

// 当 checkbox 状态改变时
const onCheckChange = (id: number | string, checkVal: boolean) => {
	const index = listData.value.findIndex(item => item.id === id);
	if (index !== -1) {
		listData.value[index].isCheck = checkVal;
		listData.value[index].status = checkVal ? 1 : 2;
	}
};

// 排序 todoList
let sortableInstance: Sortable | null = null; // 拖动排序功能实例
const sortTodoList = (length: number) => {
	if (length === 0) {
		sortableInstance && sortableInstance.destroy();
		sortableInstance = null;
	} else if (length > 1) {
		sortableInstance && sortableInstance.destroy();
		sortableInstance = Sortable.create(listContainerRef.value, {
			handle: ".list-item-sort",
			dataIdAttr: "data-key",
			animation: 150,
			onEnd: () => {
				// console.log("onEnd", sortableInstance!.toArray());
				listData.value = sortableInstance!.toArray().map(id => {
					return listData.value.find(item => item.id === Number(id))!;
				});
			},
		});
	}
};

// 缓存 todoList
const storageTodoList = debounce((data: EmptyArrayType) => {
	Local.set(`todoList--${userInfo.value.id}`, data);
}, 800);

onMounted(() => {
	const unwatch1 = watch(
		() => listData.value.length, // 监听 listData 长度的变化
		() => sortTodoList(listData.value.length),
		{ immediate: true }
	);
	const unwatch2 = watch(
		() => listData.value, // 监听 listData 值的变化
		() => storageTodoList(listData.value),
		{ deep: true }
	);
	onBeforeUnmount(() => {
		unwatch1();
		unwatch2();
	});
});
</script>

<style scoped lang="scss">
.card_header {
	display: flex;
	justify-content: space-between;
	align-items: center;
	height: 20px;
	.card_header_right {
		height: 100%;
	}
}
.list-container {
	width: 100%;
	height: 100%;
	overflow-y: auto;
	.list-item {
		display: flex;
		align-items: center;
		padding: 0 0 9px;
		margin: 0 0 10px;
		border-bottom: 1px solid #ebeef5;
		&:last-child {
			margin: 0;
		}
		.list-status {
			flex-grow: 0;
			flex-shrink: 0;
			width: 30px;
			height: 30px;
			margin-right: 15px;
		}
		.list-mid {
			flex-grow: 1;
			display: flex;
			align-items: center;
			.list-item-content {
				flex-grow: 1;
				font-size: 14px;
				color: #606266;
			}
			.list-item-sort {
				flex-grow: 0;
				flex-shrink: 0;
				margin-left: 10px;
			}
		}
		.list-right {
			flex-grow: 0;
			flex-shrink: 0;
			display: flex;
			flex-direction: column;
			margin: 0 5px 0 10px;
			.list-item-check {
				font-size: 12px;
				color: #606266;
			}
		}
	}
}
</style>
